/**
 *  Copyright (C) 2008-2013  Telosys project org. ( http://www.telosys.org/ )
 *
 *  Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, Version 3.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *          http://www.gnu.org/licenses/lgpl.html
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.telosys.common.logger;

import java.io.InputStream;
import java.util.Properties;

import org.telosys.common.TelosysException;
import org.telosys.common.config.TelosysConfig;
import org.telosys.util.StreamUtil;

public class TelosysLogger 
{
	//private static final String   TRACE_CONF_FILE    = "TraceConfFile"; // v 1.0.0
	
	//--- Logger
    private static final TelosysClassLogger $log = new TelosysClassLogger(TelosysLogger.class);

	//-----------------------------------------------------------------------------
    // PROPERTIES & CONFIGURATION
    //-----------------------------------------------------------------------------
    //--- Standard logger provided by Telosys framework
    private static LogWriter                $TelosysLogWriter     = null;

    //--- External specific application logger
    private static ApplicationLoggerFacade  $ApplicationLogger = null; // v 0.9.9

    //-----------------------------------------------------------------------------
    private static void createLogWriter(Properties prop)
    {
        if (prop != null)
        {
            $log.info("Create LogWriter with properties. ");
            $TelosysLogWriter = new LogWriter(prop);
        }
        else
        {
            $log.error("initParameters : properties = null !");
            $log.info("Create LogWriter without properties.  ");
            $TelosysLogWriter = new LogWriter();
        }
    }

//    //private static void initTraceConfig(TelosysProperties telosysProperties)
//    private static void initTraceConfig(TelosysConfig telosysConfig)
//    {
//    	//telosysProperties.getConfigFile(TRACE_CONF_FILE);
//    	
//        //--- 1) Init the Telosys trace manager
//        $log.info("INIT : Init trace properties ( file = '" + telosysConfig.getTraceConfigFileName() + "' ) ..." );
//        InputStream is = telosysConfig.getTraceConfigInputStream();
//        if ( is != null )
//        {
//            TraceConfig.init(is); 
//            Tool.closeInputStream(is);
//            $log.info("INIT : Trace manager initialized.");                                
//        }
//        else
//        {
//            $log.error("INIT : Telosys.initTraceConfig() : Cannot get TRACE CONFIG InputStream ! ");
//        }
//        
//    }    
    
    // From Telosys.java : private static void initTraceConfig()
    public static void initTraceConfig(TelosysConfig telosysConfig, IApplicationLogger appLogger )
    {
        //--- 1) Init the Telosys trace configuration
        $log.info("INIT : Init trace properties ( file = '" + telosysConfig.getTraceConfigFileName() + "' ) ..." );
        InputStream is = telosysConfig.getTraceConfigInputStream();
        if ( is != null )
        {
            TraceConfig.init(is); 
            StreamUtil.closeInputStream(is);
            $log.info("INIT : Trace manager initialized.");                                
        }
        else
        {
            $log.error("INIT : Telosys.initTraceConfig() : Cannot get TRACE CONFIG InputStream ! ");
        }
        
        //--- 2) Set up the application logger if any  ( v 0.9.9 )
        $log.info("INIT : Init application logger ..." );
//        if ( $telosysFactory != null )
//        {
//            IApplicationLogger appLogger = $telosysFactory.getApplicationLogger();
            if ( appLogger != null )
            {
                try
                {
                    $ApplicationLogger = new ApplicationLoggerFacade(appLogger);
                    $log.info("INIT : Application logger ready.");                                
                } catch (TelosysException e)
                {
                    $log.error("INIT : Telosys.initTraceConfig() : Cannot create ApplicationLoggerFacade ! ");
                }
            }
            else
            {
                $log.info("INIT : No application logger");                                
            }
//        }
//        else
//        {
//            $log.error("INIT : Telosys factory is null !");                                
//        }
            
        //--- 3) Create Log Writer
        createLogWriter( telosysConfig.getProperties() );
    }
    
    //-----------------------------------------------------------------------------
    //--- PUBLIC LOG METHODS
    //-----------------------------------------------------------------------------
    //-----------------------------------------------------------------------------
    // ERROR
    //-----------------------------------------------------------------------------
    /**
     * Logs an error message using both standard logger and specific application logger if any
     * @param sClassName
     * @param sMsg
     */
    public static void error(String sClassName, String sMsg)
    {
        if ($TelosysLogWriter != null)
        {
            $TelosysLogWriter.error(sClassName, sMsg);
        }
        else
        {
            Console.error(sClassName, sMsg);
        }
        if ( $ApplicationLogger != null ) // v 0.9.9
        {
            $ApplicationLogger.error( sClassName, sMsg);
        }
    }
    //-----------------------------------------------------------------------------
    /**
     * Logs an error message using both standard logger and specific application logger if any
     * @param sMsg
     */
    public static void error(String sMsg)
    {
        if ($TelosysLogWriter != null)
        {
            $TelosysLogWriter.error(sMsg);
        }
        else
        {
            Console.error(sMsg);
        }
        if ( $ApplicationLogger != null ) // v 0.9.9
        {
            $ApplicationLogger.error( "", sMsg);
        }
    }

    //-----------------------------------------------------------------------------
    // ERROR - Exception
    //-----------------------------------------------------------------------------
    private static String getMsg(Throwable ex)
    {
        StackTraceElement t[] = ex.getStackTrace();
        StackTraceElement loc = t[0];
        return "Exception " + ex.toString() + " in file '" + loc.getFileName() + "', method '" + loc.getMethodName() + "', line " + loc.getLineNumber();
    }
    //-----------------------------------------------------------------------------
    /**
     * Logs an exception using both standard logger and specific application logger if any
     * @param sClassName
     * @param ex
     */
    public static void error(String sClassName, Throwable ex)
    {
        if ($TelosysLogWriter != null)
        {
            $TelosysLogWriter.error(sClassName, getMsg(ex));
            $TelosysLogWriter.exeptionReport(ex);
        }
        else
        {
            Console.error(sClassName, getMsg(ex));
            Console.exeptionReport(ex);
        }
        if ( $ApplicationLogger != null ) // v 0.9.9
        {
            $ApplicationLogger.error( sClassName, ex);
        }
    }
    //-----------------------------------------------------------------------------
    /**
     * Logs an exception using both standard logger and specific application logger if any
     * @param ex
     */
    public static void error(Throwable ex)
    {
        if ($TelosysLogWriter != null)
        {
            $TelosysLogWriter.error(getMsg(ex));
            $TelosysLogWriter.exeptionReport(ex);
        }
        else
        {
            Console.error(getMsg(ex));
            Console.exeptionReport(ex);
        }
        if ( $ApplicationLogger != null ) // v 0.9.9
        {
            $ApplicationLogger.error( "", ex);
        }
    }

    //-----------------------------------------------------------------------------
    // WARN
    //-----------------------------------------------------------------------------
    /**
     * Logs a warning message using both standard logger and specific application logger if any
     * @param sClassName
     * @param sMsg
     */
    public static void warn(String sClassName, String sMsg)
    {
        if ($TelosysLogWriter != null)
        {
            $TelosysLogWriter.warn(sClassName, sMsg);
        }
        else
        {
            Console.warn(sClassName, sMsg);
        }
        if ( $ApplicationLogger != null ) // v 0.9.9
        {
            $ApplicationLogger.warn( sClassName, sMsg);
        }
    }
    //-----------------------------------------------------------------------------
    /**
     * Logs a warning message using both standard logger and specific application logger if any
     * @param sMsg
     */
    public static void warn(String sMsg)
    {
        if ($TelosysLogWriter != null)
        {
            $TelosysLogWriter.warn(sMsg);
        }
        else
        {
            Console.warn(sMsg);
        }
        if ( $ApplicationLogger != null ) // v 0.9.9
        {
            $ApplicationLogger.warn( "", sMsg);
        }
    }

    //-----------------------------------------------------------------------------
    // INFO
    //-----------------------------------------------------------------------------
    /**
     * Logs an info message using both standard logger and specific application logger if any
     * @param sClassName
     * @param sMsg
     */
    public static void info(String sClassName, String sMsg)
    {
        if ($TelosysLogWriter != null)
        {
            $TelosysLogWriter.info(sClassName, sMsg);
        }
        else
        {
            Console.info(sClassName, sMsg);
        }
        if ( $ApplicationLogger != null ) // v 0.9.9
        {
            $ApplicationLogger.info( sClassName, sMsg);
        }
    }
    //-----------------------------------------------------------------------------
    /**
     * Logs an info message using both standard logger and specific application logger if any
     * @param sMsg
     */
    public static void info(String sMsg)
    {
        if ($TelosysLogWriter != null)
        {
            $TelosysLogWriter.info(sMsg);
        }
        else
        {
            Console.info(sMsg);
        }
        if ( $ApplicationLogger != null ) // v 0.9.9
        {
            $ApplicationLogger.info( "", sMsg);
        }
    }

    //-----------------------------------------------------------------------------
    // TRACE
    //-----------------------------------------------------------------------------
    /**
     * Logs a trace message using both standard logger and specific application logger if any
     * @param sClassName
     * @param sMsg
     */
    public static void trace(String sClassName, String sMsg)
    {
        if ($TelosysLogWriter != null)
        {
            $TelosysLogWriter.trace(sClassName, sMsg);
        }
        else
        {
            Console.trace(sClassName, sMsg);
        }
        if ( $ApplicationLogger != null ) // v 0.9.9
        {
            $ApplicationLogger.trace( sClassName, sMsg);
        }
    }
    //-----------------------------------------------------------------------------
    /**
     * Logs a trace message using both standard logger and specific application logger if any
     * @param sMsg
     */
    public static void trace(String sMsg)
    {
        if ($TelosysLogWriter != null)
        {
            $TelosysLogWriter.trace(sMsg);
        }
        else
        {
            Console.trace(sMsg);
        }
        if ( $ApplicationLogger != null ) // v 0.9.9
        {
            $ApplicationLogger.trace("", sMsg);
        }
    }
    
   //-----------------------------------------------------------------------------
}
